import React, { useState, useEffect, useRef } from 'react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { tomorrow } from 'react-syntax-highlighter/dist/esm/styles/prism';
import './style.css';

export interface TypewriterEffectProps {
  /** Text to display with typewriter effect */
  text: string;
  /** Speed in milliseconds between characters */
  speed?: number;
  /** Whether to show cursor */
  showCursor?: boolean;
  /** Whether to render as Markdown */
  renderMarkdown?: boolean;
  /** Callback when typing is complete */
  onComplete?: () => void;
  /** Whether to start typing immediately */
  autoStart?: boolean;
  /** Custom className */
  className?: string;
}

/**
 * TypewriterEffect component for displaying text with typing animation.
 * Supports both plain text and Markdown rendering.
 */
export const TypewriterEffect: React.FC<TypewriterEffectProps> = ({
  text,
  speed = 30,
  showCursor = true,
  renderMarkdown = true,
  onComplete,
  autoStart = true,
  className = '',
}) => {
  const [displayedText, setDisplayedText] = useState('');
  const [currentIndex, setCurrentIndex] = useState(0);
  const [isTyping, setIsTyping] = useState(false);
  const [isComplete, setIsComplete] = useState(false);
  const intervalRef = useRef<NodeJS.Timeout | null>(null);
  const containerRef = useRef<HTMLDivElement>(null);

  // Start or stop typing based on autoStart and text changes
  useEffect(() => {
    if (autoStart && text) {
      startTyping();
    }
    
    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
      }
    };
  }, [text, autoStart]);

  // Handle typing animation
  useEffect(() => {
    if (isTyping && currentIndex < text.length) {
      intervalRef.current = setTimeout(() => {
        setDisplayedText(text.slice(0, currentIndex + 1));
        setCurrentIndex(currentIndex + 1);
      }, speed);
    } else if (isTyping && currentIndex >= text.length) {
      completeTyping();
    }

    return () => {
      if (intervalRef.current) {
        clearTimeout(intervalRef.current);
      }
    };
  }, [currentIndex, isTyping, text, speed]);

  /**
   * Start typing animation.
   */
  const startTyping = () => {
    setIsTyping(true);
    setIsComplete(false);
    setCurrentIndex(0);
    setDisplayedText('');
  };

  /**
   * Pause typing animation.
   */
  const pauseTyping = () => {
    setIsTyping(false);
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
    }
  };

  /**
   * Resume typing animation.
   */
  const resumeTyping = () => {
    if (!isComplete && currentIndex < text.length) {
      setIsTyping(true);
    }
  };

  /**
   * Skip to the end.
   */
  const skipToEnd = () => {
    setDisplayedText(text);
    setCurrentIndex(text.length);
    completeTyping();
  };

  /**
   * Complete typing.
   */
  const completeTyping = () => {
    setIsTyping(false);
    setIsComplete(true);
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
    }
    onComplete?.();
  };

  /**
   * Reset typing.
   */
  const reset = () => {
    setDisplayedText('');
    setCurrentIndex(0);
    setIsTyping(false);
    setIsComplete(false);
  };

  /**
   * Render content based on renderMarkdown prop.
   */
  const renderContent = () => {
    const content = displayedText || '';

    if (renderMarkdown) {
      return (
        <ReactMarkdown
          remarkPlugins={[remarkGfm]}
          components={{
            code({ node, inline, className, children, ...props }) {
              const match = /language-(\w+)/.exec(className || '');
              return !inline && match ? (
                <SyntaxHighlighter
                  style={tomorrow}
                  language={match[1]}
                  PreTag="div"
                  {...props}
                >
                  {String(children).replace(/\n$/, '')}
                </SyntaxHighlighter>
              ) : (
                <code className={className} {...props}>
                  {children}
                </code>
              );
            },
          }}
        >
          {content}
        </ReactMarkdown>
      );
    }

    return <span>{content}</span>;
  };

  return (
    <div
      ref={containerRef}
      className={`typewriter-container ${className}`}
    >
      <div className="typewriter-content">
        {renderContent()}
        {showCursor && !isComplete && (
          <span className="typewriter-cursor">|</span>
        )}
      </div>
      
      {/* Control buttons (optional, can be hidden via CSS) */}
      <div className="typewriter-controls">
        {!isTyping && !isComplete && (
          <button onClick={startTyping} className="typewriter-button">
            Start
          </button>
        )}
        {isTyping && (
          <button onClick={pauseTyping} className="typewriter-button">
            Pause
          </button>
        )}
        {!isTyping && !isComplete && currentIndex > 0 && (
          <button onClick={resumeTyping} className="typewriter-button">
            Resume
          </button>
        )}
        {isTyping && (
          <button onClick={skipToEnd} className="typewriter-button">
            Skip
          </button>
        )}
        {isComplete && (
          <button onClick={reset} className="typewriter-button">
            Reset
          </button>
        )}
      </div>
    </div>
  );
};

export default TypewriterEffect;